<?php
/**
 * Core_Form
 * 
 * @author naspeh
 * @version $Id: Form.php 659 2008-06-15 11:34:26Z naspeh $
 */
class Core_Form extends Zend_Form
{
    /**
     * Первый элемент
     *
     */
    const FIRST_ELEMENT = '_first';
    /**
     * Счетчик форм
     *
     * @var integer
     */
    protected static $_count = 0;
    /**
     * Хэш-элемент
     *
     * @var Zend_Form_Element_Hash
     */
    protected static $_hashElement = null;
    /**
     * Флаг необходимости хэша
     *
     * @var boolean
     */
    protected $_withHash = true;
    /**
     * Параметры
     *
     * @var array
     */
    protected $_params = array();
    /**
     * Конструктор
     *
     * @param array $options
     */
    public function __construct(array $options = null)
    {
        parent::__construct($options);
        $this->setName(self::buildName());
        $this->setIsArray(true); 
        $this->setDecorators(array(
            'FormElements',
            'Form',
            array('HtmlTag', array('tag' => 'div')),
        ));                
        if ($this->getWithHash()) {
            $this->addElement($this->getHashElement());
        }
        $this->init();
    }
    /**
     * Инициализация
     *
     * @return Core_Form
     */
    public function init()
    {
        return $this;    
    }
    /**
     * Устанавливает опции
     *
     * @param array $options
     * @return Core_Form
     */
    public function setOptions(array $options)
    {
        if (isset($options['name'])) {
            unset($options['name']);
        }
        parent::setOptions($options);
        return $this;                
    }
    /**
     * Устанавливает флаг необходимости хэша
     *
     * @param boolean $flag
     * @return Core_Form
     */
    public function setWithHash($flag)
    {
        $this->_withHash = (bool) $flag;
        return $this;
    }
    /**
     * Возвращает флаг необходимости хэша
     *
     * @return unknown
     */
    public function getWithHash()
    {
        return $this->_withHash;
    }
    /**
     * Возвращает хэш-элемент
     *
     * @return Zend_Form_Element_Hash
     */
    public function getHashElement()
    {
        if (is_null(self::$_hashElement)) {
        	self::$_hashElement = new Zend_Form_Element_Hash(self::FIRST_ELEMENT, array(
                'salt' => 'unique', 
                'order'=>0,
                'decorators' => array(
                    'ViewHelper',
                    'Errors',
                )     
            )); 
        }
        return self::$_hashElement;
    }
    /**
     * Устанавливает параметры
     *
     * @param array $params
     * @return Core_Form
     */
    public function setParams(array $params)
    {
        $this->_params = $params;
        return $this;
    }
    /**
     * Возвращает параметры/параметр
     *
     * @param string $name
     * @return mixed
     */
    public function getParams($name = null)
    {
        if (isset($name)) {
        	if (isset($this->_params[$name])) {
        		return $this->_params[$name];
        	}
        	return  false;
        }
        return $this->_params;
    }
    /**
     * Устанавливает вторичную проверку валидности
     *
     * @return Core_Form
     */
    protected function _setPostValid()
    {
        return $this;
    }
	/**
	 * Проверяет валидность
	 *
	 * @param Zend_Controller_Request_Http|array $data
	 * @return boolean
	 */
	public function isValid($data) 
	{
	    if ($data instanceof Zend_Controller_Request_Http) {
	    	if (null !== $data->getPost($this->getName(), null)) {
	    		$data = $data->getPost();
	    	} else {
	    		return false;
	    	}
	    }
        if (parent::isValid($data)) {
           $this->_setPostValid();
           return parent::isValid($data);
        } else {
           return false;
        }
	}
	/**
	 * Строит имя
	 *
	 * @return string
	 */
	public static function buildName()
	{
        $request = Core_Controller_Front::getInstance()->getRequest();
        if ($request instanceof Zend_Controller_Request_Abstract) {
            $name = array($request->getModuleName(), $request->getControllerName(), $request->getActionName());
        	if (0 < self::$_count) {
        		$name[]= self::$_count;
        	}
        	self::$_count++;
        	$name = implode('_', $name);
        } else {
        	$name = 'form';
        }
        return $name;
	}
	/**
	 * Инициализирует элементы
	 *
	 * @return Core_Form
	 */
	public function initElements()
	{
	    foreach ($this->getElements() as $element) {
	    	$element->setBelongsTo($this->getElementsBelongTo());
	    }
	    foreach ($this->getSubForms() as $subForm) {
	        foreach ($subForm->getElements() as $element) {
	            $belongTo = $this->getElementsBelongTo() . '[' . $subForm->getElementsBelongTo() . ']';
	        	$element->setBelongsTo($belongTo);
	        }
	    }
	    return $this;
	}
    /**
     * Add a new element
     *
     * $element may be either a string element type, or an object of type 
     * Zend_Form_Element. If a string element type is provided, $name must be 
     * provided, and $options may be optionally provided for configuring the 
     * element.
     *
     * If a Zend_Form_Element is provided, $name may be optionally provided, 
     * and any provided $options will be ignored.
     * 
     * @param  string|Zend_Form_Element $element 
     * @param  string $name 
     * @param  array|ZendConfig $options 
     * @return Zend_Form
     */
    public function addElement($element, $name = null, $options = null)
    {
        $options['disableLoadDefaultDecorators'] = true;
        parent::addElement($element, $name, $options);
        if (null === $name) {
            $name = $element->getName();
        }        
        $element = $this->getElement($name);
        $decorators = $element->getDecorators();
        if (empty($decorators)) {
            switch (get_class($element)) {
            	case 'Zend_Form_Element_Button':
                case 'Zend_Form_Element_Submit':
                case 'Zend_Form_Element_Reset':
                    $element->setDecorators(array(
                        'ViewHelper',
                        array(array('data' => 'HtmlTag'), array('tag' => 'div')),
                    ));                                	    
            		break;
            	default:
                    $element->setDecorators(array(
                        'ViewHelper',
                        'Errors',
                        array('Description', array('tag' => 'div', 'class' => 'small')),
                        array(array('data' => 'HtmlTag'), array('tag' => 'div')),
                        array('Label', array('tag' => 'div')),
                    ));             	    
            		break;
            }
        }
        return $this;
    }
}